﻿using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace CodeContrib.Collections.Generic
{
	public class LazyList<T> : IList<T>
	{
		private IList<T> _inner;

		public int Count
		{
			get { return Inner.Count; }
		}

		public IList<T> Inner
		{
			get
			{
				if (_inner == null)
				{
					_inner = Query.ToList();
				}

				return _inner;
			}
			private set { _inner = value; }
		}

		public bool IsReadOnly
		{
			get { return Inner.IsReadOnly; }
		}

		private IQueryable<T> Query { get; set; }

		public T this[int index]
		{
			get { return Inner[index]; }
			set { Inner[index] = value; }
		}

		public LazyList(IQueryable<T> query)
		{
			Guard.NotNull(query, "query");

			Query = query;
		}

		public void Add(T item)
		{
			Inner = Inner ?? new List<T>();
			Inner.Add(item);
		}

		public void Clear()
		{
			if (_inner != null)
			{
				Inner.Clear();
			}
		}

		public bool Contains(T item)
		{
			return Inner.Contains(item);
		}

		public void CopyTo(T[] array, int arrayIndex)
		{
			Inner.CopyTo(array, arrayIndex);
		}

		public IEnumerator GetEnumerator()
		{
			return ((IEnumerable)Inner).GetEnumerator();
		}

		IEnumerator<T> IEnumerable<T>.GetEnumerator()
		{
			return Inner.GetEnumerator();
		}

		public int IndexOf(T item)
		{
			return Inner.IndexOf(item);
		}

		public void Insert(int index, T item)
		{
			Inner.Insert(index, item);
		}

		public bool Remove(T item)
		{
			return Inner.Remove(item);
		}

		public void RemoveAt(int index)
		{
			Inner.RemoveAt(index);
		}
	}
}